/*
 *  Name		: CMX7164.c
 *	Author	 	: Tigran Papazyan
 *  Created on	: Dec 6, 2010
 *  Copyright   : Copyright Antel Systems
 *  Description : CMX7164 Driver
 */

#include "CMX7164.h"
#include "cmx7164_api.h"
#include "CMX998.h"
#include "CMX994.h"
#include "LMX2541.h"
#include "usart_fast.h"
#include "spi.h"
#include "intc.h"
#include "gpio.h"
#include "at25dfx.h"
#include "file_system.h"
#include "llc/llc.h"
#include "mac/mac.h"
#include "tc_1.h"
#include "cycle_counter.h"
#include "eic.h"
#include "AntelCfgOID.h"
#include "CfgParams.h"
#include "delay.h"
#include "pcc/pcc.h"
#include <math.h>
#include "network.h"

#if FOSC == 19200000
#define TCXO_19_2
#elif FOSC == 12288000
#define TCXO_12_288
#elif FOSC == 16000000
#define TCXO_16
#endif

/*********************************************************************************************/
const unsigned int BlockSize_QAM[] = { 15, 60, 33, 37, 44, 176, 73, 292, 88, 352, 104, 416 };
const unsigned int BlockSize_GMSK[] = { 4, 6, 12, 18 };
const unsigned int BlockSize_4FSK[] = { 6, 9, 12 };

const float Sin_Table[64] =
{
		0.024541 ,0.049068 ,0.073565 ,0.098017 ,0.122411 ,0.146730 ,0.170962 ,0.195090 ,0.219101 ,0.242980 ,0.266713 ,0.290285 ,0.313682 ,0.336890 ,0.359895 ,0.382683 ,
		0.405241 ,0.427555 ,0.449611 ,0.471397 ,0.492898 ,0.514103 ,0.534998 ,0.555570 ,0.575808 ,0.595699 ,0.615232 ,0.634393 ,0.653173 ,0.671559 ,0.689541 ,0.707107 ,
		0.724247 ,0.740951 ,0.757209 ,0.773010 ,0.788346 ,0.803208 ,0.817585 ,0.831470 ,0.844854 ,0.857729 ,0.870087 ,0.881921 ,0.893224 ,0.903989 ,0.914210 ,0.923880 ,
		0.932993 ,0.941544 ,0.949528 ,0.956940 ,0.963776 ,0.970031 ,0.975702 ,0.980785 ,0.985278 ,0.989177 ,0.992480 ,0.995185 ,0.997290 ,0.998795 ,0.999699 , 1
};

/*********************************************************************************************/
short freq_err_val[FREQ_MATRIX_SIZE];
unsigned int freq_err_val_index = 0;

unsigned char CMX_nInitialized;
unsigned short CMX7164_Modulation_Type;

Timer_Tik CMX7164_TimeOut;

double CMX7164_RAM_DAC_V = 2.7;

unsigned char CMX7164_Interrupt_Event = 0;
unsigned char CMX7164_Reinit = 0;

/*********************************************************************************************/
void CMX_delay(int ms)
{
	if (Rtos_started == 1)
		delay_ms(ms);
	else
		cpu_delay_ms(ms, FMCK_HZ);
}
/*********************************************************************************************/

/*********************************************************************************************/
void CMX7164_IO_Init(void)
{
	static const gpio_map_t CMX7164_GPIO_MAP = { { CMX7164_GPIO_IRQ_PIN,CMX7164_GPIO_IRQ_FUNCTION } };
	gpio_enable_module(CMX7164_GPIO_MAP, sizeof(CMX7164_GPIO_MAP)/ sizeof(CMX7164_GPIO_MAP[0]));
	gpio_set_gpio_pin(CMX7164_RESET_PIN);
	gpio_clr_gpio_pin(TXEN_OUTPUT_PIN);
	gpio_set_gpio_pin(TRANSCEIVER_SHDN_OUTPUT_PIN);
}
/*********************************************************************************************/
/*********************************************************************************************/
void CMX7164_Disable_Interrupt(void)
{
	irq_enable.Word_val = 0x0000; //6C
	CMX7164_Write_WORD((CMX_WORD*) &irq_enable);
}
/*********************************************************************************************/

/*********************************************************************************************/
#if __GNUC__
__attribute__((__interrupt__))
#elif __ICCAVR32__
__interrupt
#endif
static void CMX7164_IRQ_Handler(void)
{
	CMX7164_Read_WORD((CMX_WORD*) &irq_status);
	CMX7164_Interrupt_Event = 1;
	eic_clear_interrupt_line(&AVR32_EIC, EXT_INT6);
	xTaskResumeFromISR(mac_task_handle);
}
/*********************************************************************************************/

/*********************************************************************************************/
void CMX7164_Set_Interrupt_Source(unsigned short Source_bit)
{
	irq_enable.Word_val = 0x8000 | (1 << Source_bit); //6C
	CMX7164_Write_WORD((CMX_WORD*) &irq_enable);
}
/*********************************************************************************************/

/*********************************************************************************************/
void CMX7164_IDLE(void)
{
	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; //6B
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	CMX7164_Check_Status(Reg_Done_Bit);
	CMX7164_Disable_Interrupt();
}

/*********************************************************************************************/
char CMX7164_Flash_FIFOs(void)
{
	reg_done_select.Word_val = 0x0002; //69	set REG_DONE -> FLASH FIFO
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; //	@x50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	return CMX7164_Check_Status(Reg_Done_Bit);
}

/*********************************************************************************************/
static void CMX7164_chipselect_df(Bool bSelect)
{
	if (bSelect)
	{
		// Select SPI chip.
		spi_selectChip(SPI_MODULE, CMX7164_SPI_NPCS);
	}
	else
	{
		// Unselect SPI chip.
		spi_unselectChip(SPI_MODULE, CMX7164_SPI_NPCS);
	}
}
/*********************************************************************************************/

/*********************************************************************************************/
char CMX7164_SPI_Write(unsigned char address, unsigned char* in,unsigned int len)
{
	CMX7164_chipselect_df(TRUE);

	spi_write(SPI_MODULE, address);

	while (len)
	{
		spi_write(SPI_MODULE, *in);
		in++;
		len--;
	}
	CMX7164_chipselect_df(FALSE);

	return SPI_OK;
}
/*********************************************************************************************/

/*********************************************************************************************/
char CMX7164_SPI_Read(unsigned char address, unsigned char* out,unsigned int len)
{
	unsigned short temp;
	CMX7164_chipselect_df(TRUE);

	spi_write(SPI_MODULE, address);

	while (len)
	{
		spi_write_dummy();
		spi_read(SPI_MODULE, &temp);
		*out = temp & 0xFF;
		out++;
		len--;
	}
	CMX7164_chipselect_df(FALSE);
	return SPI_OK;
}
/*********************************************************************************************/

/******************************* Read , Write , Status functions *****************************/

void CMX7164_Read_WORD(CMX_WORD* Pointer)
{
	CMX7164_SPI_Read(Pointer->address, (unsigned char*) &Pointer->data, 2);
}

void CMX7164_Read_BYTE(CMX_BYTE* Pointer)
{
	CMX7164_SPI_Read(Pointer->address, &Pointer->data, 1);
}

void CMX7164_Write_WORD(CMX_WORD* Pointer)
{
	CMX7164_SPI_Write(Pointer->address, (unsigned char*) &Pointer->data, 2);
}

void CMX7164_Write_BYTE(CMX_BYTE* Pointer)
{
	CMX7164_SPI_Write(Pointer->address, &Pointer->data, 1);
}

int CMX7164_Check_Status(unsigned short Status_Reg_Bit_Num)
{
	int status = 0;
	int Time_out = 1000;
	while (Time_out > 0 && status == 0)
	{
		CMX7164_Read_WORD((CMX_WORD*) &irq_status);
		status = irq_status.Word_val & (1 << Status_Reg_Bit_Num);
		Time_out--;
	}
	if (Time_out == 0)
	{
		Time_out = 0;
		return 1;
	}
	return 0;
}
/******************************* END Read , Write , Status functions *************************/

/*********************************************************************************************/
void CMX7164_SET_I_Q_Output_Coarse_Gain(void)
{
	I_output_coarse_gain.Word_val = 0x0000;
	CMX7164_Write_WORD((CMX_WORD*) &I_output_coarse_gain);
	Q_output_coarse_gain.Word_val = 0x0000;
	CMX7164_Write_WORD((CMX_WORD*) &Q_output_coarse_gain);
}
/*********************************************************************************************/

/*********************************************************************************************/
void CMX7164_Reg_Init(void)
{
	C_BUS_Reset = C_BUS_RESET; //0x01
	modem_command_fifo_data_byte.address = MODEM_COMMAND_FIFO_DATA_BYTE; //0x48
	modem_command_fifo_data_word.address = MODEM_COMMAND_FIFO_DATA_WORD; //0x49
	modem_command_control_byte.address = MODEM_COMMAND_CONTROL_BYTE; //0x4A
	modem_command_fifo_level.address = MODEM_COMMAND_FIFO_LEVEL; //0x4B
	rx_fifo_data_byte.address = RX_FIFO_DATA_BYTE; //0x4C
	rx_fifo_data_word.address = RX_FIFO_DATA_WORD; //0x4D
	rx_fifo_control_byte.address = RX_FIFO_CONTROL_BYTE; //0x4E
	rx_fifo_level.address = RX_FIFO_LEVEL; //0x4F
	fifo_control.address = FIFO_CONTROL; //0x50
	aux_adc_0_control.address = AUX_ADC_0_CONTROL; //0x51
	aux_adc_1_control.address = AUX_ADC_1_CONTROL; //0x52
	aux_adc_2_control.address = AUX_ADC_2_CONTROL; //0x53
	aux_adc_3_control.address = AUX_ADC_3_CONTROL; //0x54
	aux_adc_0_thresholds.address = AUX_ADC_0_THRESHOLDS; //0x55
	aux_adc_1_thresholds.address = AUX_ADC_1_THRESHOLDS; //0x56
	aux_adc_2_thresholds.address = AUX_ADC_2_THRESHOLDS; //0x57
	aux_adc_3_thresholds.address = AUX_ADC_3_THRESHOLDS; //0x58
	aux_dac_0_control.address = AUX_DAC_0_CONTROL; //0x59
	aux_dac_1_control.address = AUX_DAC_1_CONTROL; //0x5A
	aux_dac_2_control.address = AUX_DAC_2_CONTROL; //0x5B
	aux_dac_3_control.address = AUX_DAC_3_CONTROL; //0x5C
	aux_adc_0_read.address = AUX_ADC_0_READ; //0x71
	aux_adc_1_read.address = AUX_ADC_1_READ; //0x72
	aux_adc_2_read.address = AUX_ADC_2_READ; //0x73
	aux_adc_3_read.address = AUX_ADC_3_READ; //0x74
	I_output_control.address = I_OUTPUT_CONTROL; //0x5D
	Q_output_control.address = Q_OUTPUT_CONTROL; //0x5E
	I_input_control.address = I_INPUT_CONTROL; //0x5F
	Q_input_control.address = Q_INPUT_CONTROL; //0x60
	signal_control.address = SIGNAL_CONTROL; //0x61
	agc_control.address = AGC_CONTROL; //0x65
	rx_tracking.address = RX_TRACKING; //0x66
	reg_done_select.address = REG_DONE_SELECT; //0x69
	internal_buffer_fill_levels.address = INTERNAL_BUFFER_FILL_LEVELS; //0x70
	I_input_offset.address = I_INPUT_OFFSET; //0x75
	Q_input_offset.address = Q_INPUT_OFFSET; //0x76
	agc_gain_rssi.address = AGC_GAIN_RSSI; //0x77
	rx_error_magnitude.address = RX_ERROR_MAGNITUDE; //0x7A
	frequency_error.address = FREQUENCY_ERROR; //0x7B
	spi_talkthrough_address.address = SPI_TALKTHROUGH_ADDRESS; //0x62
	spi_talkthrough_write.address = SPI_TALKTHROUGH_WRITE; //0x63
	gpio_control.address = GPIO_CONTROL; //0x64
	spi_talkthrough_read.address = SPI_TALKTHROUGH_READ; //0x78
	gpio_read.address = GPIO_READ; //0x79
	programming.address = PROGRAMMING; //0x6A
	modem_mode_and_control.address = MODEM_MODE_AND_CONTROL; //0x6B
	irq_enable.address = IRQ_ENABLE; //0x6C
	irq_status.address = IRQ_STATUS; //0x7E
	modem_control_readback.address = MODEM_CONTROL_READBACK; //0x7F
	I_Q_input_config.address = I_Q_INPUT_CONFIG; //0xB0
	I_input_coarse_gain.address = I_INPUT_COARSE_GAIN; //0xB1
	Q_input_coarse_gain.address = Q_INPUT_COARSE_GAIN; //0xB2
	I_Q_output_config.address = I_Q_OUTPUT_CONFIG; //0xB3
	I_output_coarse_gain.address = I_OUTPUT_COARSE_GAIN; //0xB4
	Q_output_coarse_gain.address = Q_OUTPUT_COARSE_GAIN; //0xB5
	vbias_control.address = VBIAS_control; //0xB7
}
/*********************************************************************************************/

void CMX7164_IRQ_Init(void)
{
	eic_options_t eic_options; // Structure holding the configuration parameters
	// of the EIC module.
	CMX7164_Disable_Interrupt();
	// Enable level-triggered interrupt.
	eic_options.eic_mode = EIC_MODE_EDGE_TRIGGERED;
	// Interrupt will trigger on falling edge.
	eic_options.eic_edge = EIC_EDGE_FALLING_EDGE;
	// Disable filter.
	eic_options.eic_filter = EIC_FILTER_DISABLED;
	// For Wake Up mode, initialize in asynchronous mode
	eic_options.eic_async = EIC_SYNCH_MODE;
	// Choose External Interrupt Controller Line
	eic_options.eic_line = EXT_INT6; // Enable the chosen external interrupt line.

	Disable_global_interrupt();
	// Init the EIC controller with the options
	eic_init(&AVR32_EIC, &eic_options, 1);
	// Enable External Interrupt Controller Line
	eic_enable_line(&AVR32_EIC, EXT_INT6);

	INTC_register_interrupt(&CMX7164_IRQ_Handler, AVR32_EIC_IRQ_6,AVR32_INTC_INT1);

	eic_enable_lines(&AVR32_EIC, (1 << eic_options.eic_line));
	eic_enable_interrupt_lines(&AVR32_EIC, (1 << eic_options.eic_line));

	Enable_global_interrupt();
}

int CMX7164_Set_Cannel_Spec(unsigned short Spacing)
{
#ifdef _STANDARDS
	switch (Spacing)
	{
	case 0:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(600, 9600);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_9600))
			return 2;
		break;
	case 1:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(300, 4800);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_4800))
			return 2;
		break;
	case 2:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(150, 2400);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_2400))
			return 2;
		break;
	case 3:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(250, 4000);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_4000))
			return 2;
		break;
	case 4:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(450, 7200);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_7200))
			return 2;
		break;
	case 5:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(500, 8000);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_8000))
			return 2;
		break;
/*	case 6:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(750, 12000);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_12000))
			return 2;
		break;*/
	case 7:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(900, 14400);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_14400))
			return 2;
		break;
	case 8:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(1000, 16000);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_16000))
			return 2;
		break;
/*	case 25000 :
	 if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_20480))
	 return 2 ;
	 break ;*/
	default:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(600, 9600);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_9600))
			return 2;
		break;
	}
#else
	switch(Spacing)
	{
		case 25000 :
		if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_20480))
		return 2;
		CMX994_Write(0x12 , 0x14); //MixPwr ,IQPwr,LNAPwr , DC-Norm , Divide - 2 ,ACRFlt Max
		break;
		case 12500 :
		if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_9600))
		return 2;
		CMX994_Write(0x12 , 0x0C); //MixPwr ,IQPwr,LNAPwr , DC-Norm , Divide - 2 ,ACRFlt Int.
		break;
		case 6250 :
		if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_4800))
		return 2;
		CMX994_Write(0x12 , 0x04); //MixPwr ,IQPwr,LNAPwr , DC-Norm , Divide - 2 ,ACRFlt Min
		break;
		default :
		if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_20480))
		return 2;
		CMX994_Write(0x12 , 0x14); //MixPwr ,IQPwr,LNAPwr , DC-Norm , Divide - 2 ,ACRFlt Max
		break;
	}
#endif
	CMX7164_Reinitialize();
	return 0;
}

/*********************************************************************************************/
int CMX7164_Initialize(void)
{
	//	unsigned short antenna_protection ;
	int symbol_rate ;
	CMX7164_Reg_Init();
	CMX7164_Modulation_Type = ConfigRoot.G_Wireless.SG_Uhf.param_modulation;
	switch (CMX7164_Modulation_Type)
	{
	case 1:
	case 2:
	case 3:
		CMX7164_Set_FEC();
		if (CMX7164_Image_loading(CMX7164_QAM_MODULATION))
			return 1;
		break;
	case 4:
	case 5:
		CMX7164_Set_FEC();
		if (CMX7164_Image_loading(CMX7164_FSK_MODULATION))
			return 1;
		break;
	case 6:
		CMX7164_Set_FEC();
		if (CMX7164_Image_loading(CMX7164_GMSK_MODULATION))
			return 1;
		break;
	default:
		CMX7164_Modulation_Type = 1;
		CMX7164_Set_FEC();
		if (CMX7164_Image_loading(CMX7164_QAM_MODULATION))
			return 1;
		break;
	}

	if(ConfigRoot.G_Wireless.SG_Uhf.param_carrier_freq_number == 0)
		symbol_rate = Current_Channel.sym_rate ;
	else
		symbol_rate = ConfigRoot.G_Wireless.SG_Uhf.param_freq_number_symbolrate ;

#ifdef _STANDARDS
	switch (symbol_rate)
	{
	case 0:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(600, 9600);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_9600))
			return 2;
		break;
	case 1:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(300, 4800);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_4800))
			return 2;
		break;
	case 2:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(150, 2400);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_2400))
			return 2;
		break;
	case 3:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(250, 4000);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_4000))
			return 2;
		break;
	case 4:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(450, 7200);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_7200))
			return 2;
		break;
	case 5:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(500, 8000);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_8000))
			return 2;
		break;
	case 6:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(750, 12000);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_12000))
			return 2;
		break;
	case 7:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(900, 14400);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_14400))
			return 2;
		break;
	case 8:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(1000, 16000);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_16000))
			return 2;
		break;
/*	case 25000 :
	 if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_20480))
	 return 2 ;
	 break ;*/
	default:
		if (CMX7164_Modulation_Type > 3)
			CMX7164_FSK_GMSK_set_deviation(600, 9600);
		if (CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_9600))
			return 2;
		break;
	}
#else
	switch(symbol_rate)
	{
		case 25000 :
		if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_20480))
		return 2;
		CMX994_Write(0x12 , 0x14); //MixPwr ,IQPwr,LNAPwr , DC-Norm , Divide - 2 ,ACRFlt Max
		break;
		case 12500 :
		if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_9600))
		return 2;
		CMX994_Write(0x12 , 0x0C); //MixPwr ,IQPwr,LNAPwr , DC-Norm , Divide - 2 ,ACRFlt Int.
		break;
		case 6250 :
		if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_4800))
		return 2;
		CMX994_Write(0x12 , 0x04); //MixPwr ,IQPwr,LNAPwr , DC-Norm , Divide - 2 ,ACRFlt Min
		break;
		default :
		if(CMX7164_Boud_Rate_Operation(CMX7164_BOUD_RATE_20480))
		return 2;
		CMX994_Write(0x12 , 0x14); //MixPwr ,IQPwr,LNAPwr , DC-Norm , Divide - 2 ,ACRFlt Max
		break;
	}
#endif
	vbias_control.Word_val = 0x0001; //B7 BIAS must be enabled for ADC operation
	CMX7164_Write_WORD((CMX_WORD*) &vbias_control);

	if (CMX7164_SSOUT_Port_Config())
		return 3;

	if (CMX7164_GPIO_config())
		return 4;

	if (CMX7164_RAMDAC_Config(CMX7164_RAM_DAC_NORMAL_OPERATION))
		return 5;
	CMX7164_Invert_I_Q();

	CMX7164_Set_modulation_type(CMX7164_Modulation_Type);

	CMX7164_AGC_Config();

	CMX7164_SET_I_Q_Output_Coarse_Gain();

	if (CMX7164_Flash_FIFOs())
		return 7;

	//	CMX7164_TX_DC_Offset_Correction(ConfigRoot.WirelessLink.WirelessLink.Pow.value);
	CMX7164_IO_Filter_Bendwidth_select(INPUT_RRC_FILTER_100K, OUTPUT_RRC_FILTER_50K);

	//	antenna_protection = CMX998_NC_Antenna_protection() ;

	/*	if(antenna_protection < 535 )
	 CMX7164_RX_Enable(1);
	 else
	 {
	 printk("PROBLEM WITH ANTENNA CONNECTION");
	 }*/

	//CMX7164_Tx_DC_Calibration_Setup();

	CMX7164_RX_Enable(1);
	CMX7164_IRQ_Init();


//	CMX7164_set_Preamble_len(0x30, 0x1E);
	/*	if(CMX7164_set_FS_len(24))
	 return 1 ;

	 if(CMX7164_set_preamble_len(0x20 , 0xFC))
	 return 1 ;
	 */
	signal_control.Word_val = 0 ;
	CMX7164_Write_WORD((CMX_WORD*) &signal_control);

	return 0;
}
/*********************************************************************************************/

void CMX7164_Packet_init(unsigned char packet_type)
{
	switch (packet_type)
	{
	case TRIM_PACKET:
		CMX7164_set_Preamble_len(0xFF, 0xC0); //255 symbol , data = 0xC0
		CMX7164_set_FS_len(2, 0xFC03, 0, 0);
		CMX7164_set_Teil_len(16, 0x7E7E);
		break;
	}
}

/***************************** Configuring for X Baud Operation ******************************/

int CMX7164_Boud_Rate_Operation(unsigned char Boud_rate)
{
#ifdef TCXO_16
	reg_done_select.Word_val = 0x0008; //69	set REG_DONE -> Mode
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);

	modem_mode_and_control.Word_val = 0x0010; // Program Block 1
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
		return 1;

	reg_done_select.Word_val = 0x0001; //69	set REG_DONE -> PROG
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	programming.Program_Block_Data = 0x7A00; // 128Hz sampling			1.0
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x0001; // Idle int. clock div.		1.1
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
		return 1;

	if ((CMX7164_Modulation_Type == 4) || (CMX7164_Modulation_Type == 5)/*FSK modulations*/)
	{
		switch (Boud_rate)
		{
		case CMX7164_BOUD_RATE_16000:
			programming.Program_Block_Data = 5; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 32; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 20; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2B59; // Main PLL Con						1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 16000; // baud rate 16000					1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable				1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;
		case CMX7164_BOUD_RATE_14400:
			programming.Program_Block_Data = 25; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 144; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 20; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x26A7; // Main PLL Con						1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 14400; // baud rate 16000					1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable				1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_8000:
			programming.Program_Block_Data = 5; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 16; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 20; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2A53; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 8000; // baud rate 8000				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_4000:
			programming.Program_Block_Data = 2; // Ref clock div. Rx or Tx mode 	1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 8; // PLL clock div. Rx or Tx mode		1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.			1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 50; // IQ IO clock div.					1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2E25; // Main PLL Con						1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 4000; // baud rate 4000					1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable				1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_9600:
			programming.Program_Block_Data = 25; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 96; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 20; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x25A3; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 9600; // baud rate 9600				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_7200:
			programming.Program_Block_Data = 25; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 72; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 20; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x25A1; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 7200; // baud rate 7200				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_4800:
			programming.Program_Block_Data = 5; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 24; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 50; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2B55; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 4800; // baud rate 4800				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;
		case CMX7164_BOUD_RATE_2400:
			programming.Program_Block_Data = 5; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 12; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 50; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2A51; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 2400; // baud rate 2400				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;
		}
	}
	else /*QAM GMSK modulations*/
	{
		switch (Boud_rate)
		{
		case CMX7164_BOUD_RATE_20480:
			programming.Program_Block_Data = 25; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 328; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 3; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 32; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2B5F; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 20480; // baud rate 20480				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_16000:
			programming.Program_Block_Data = 5; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 32; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 20; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2B59; // Main PLL Con						1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 16000; // baud rate 16000					1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

		case CMX7164_BOUD_RATE_14400:
			programming.Program_Block_Data = 25; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 144; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 20; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x26A7; // Main PLL Con						1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 14400; // baud rate 14400					1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable				1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_9600:
			programming.Program_Block_Data = 5; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 24;	// PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 25;					// IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2B55; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 9600; // baud rate 9600				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_7200:
			programming.Program_Block_Data = 5; // Ref clock div. Rx or Tx mode 	1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 18; // PLL clock div. Rx or Tx mode		1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.			1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 25; // IQ IO clock div.					1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2A53; // Main PLL Con						1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 7200; // baud rate 7200					1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

		case CMX7164_BOUD_RATE_8000:
			programming.Program_Block_Data = 2; // Ref clock div. Rx or Tx mode 	1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 8; // PLL clock div. Rx or Tx mode		1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.			1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 25; // IQ IO clock div.					1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2E25; // Main PLL Con						1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 8000; // baud rate 8000					1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable				1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_4800:
			programming.Program_Block_Data = 5; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 12; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 25; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2A51; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 4800; // baud rate 8000				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_4000:
			programming.Program_Block_Data = 2; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 8; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 50; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2E25; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 4000; // baud rate 8000				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;

		case CMX7164_BOUD_RATE_2400:
			programming.Program_Block_Data = 2; // Ref clock div. Rx or Tx mode 1.2
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 12; // PLL clock div. Rx or Tx mode	1.3
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 1; // Rx/Tx int. clock div.		1.4
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
				return 1;
			programming.Program_Block_Data = 125; // IQ IO clock div.				1.5
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			programming.Program_Block_Data = 0x2E27; // Main PLL Con					1.6
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			modem_mode_and_control.Word_val = 0x0D10;
			CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
			programming.Program_Block_Data = 2400; // baud rate 2400				1.13
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;

			programming.Program_Block_Data = 0x00; // XTAL driver disable			1.14
			CMX7164_Write_WORD((CMX_WORD*) &programming);
			if (CMX7164_Check_Status(Reg_Done_Bit))
				return 1;
			break;
		}
	}
#endif
	return 0;
}

/************************* END Configuring for X Baud Operation ******************************/

/***********************************************************************************/
int CMX7164_SYSCLK_Config(void)
{
	reg_done_select.Word_val = 0x0008; //69	set REG_DONE -> Mode
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0710; // Program Block 1 subblock 7
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	reg_done_select.Word_val = 0x0001; //69	set REG_DONE -> PROG
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	programming.Program_Block_Data = 0x0029; // SYSCLKCON
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	programming.Program_Block_Data = 0x8028; // SYSCLKDIV1
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	programming.Program_Block_Data = 0x8028; // SYSCLKDIV2
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	programming.Program_Block_Data = 0x0000; // SYSPLLCON0
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	modem_mode_and_control.Word_val = 0x0B10;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);

	programming.Program_Block_Data = 0x0E50; // SYSPLLCON1
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	programming.Program_Block_Data = 0x0003; // SYSPLLCON2
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	return 0;
}
/**********************************************************************************/

/********************************* TX DC Calibration ******************************/
int CMX7164_Tx_DC_Calibration_Setup(void)
{
	I_output_control.Word_val = 0x3100;//0x31C2 ;
	CMX7164_Write_WORD((CMX_WORD*) &I_output_control);
	Q_output_control.Word_val = 0x3100;//0x31C2 ;
	CMX7164_Write_WORD((CMX_WORD*) &Q_output_control);

	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0F50; //0x6B
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	//Disable DC Calibration
	reg_done_select.Word_val = 0x0001; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);

	programming.Program_Block_Data = 0x800A; //0x6A = 0x8000		P5.15
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x8012; //0x6A = 0x8012		P5.16
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x801F; //0x6A = 0x801F		P5.17
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x802C; //0x6A = 0x802C		P5.18
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x8039; //0x6A = 0x8039		P5.19
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x803A; //0x6A = 0x803A		P5.20
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x804A; //0x6A = 0x804A		P5.21
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x8057; //0x6A = 0x8057		P5.22
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x8058; //0x6A = 0x8058		P5.23
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x001D; //0x6A = 29			P5.24
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x8000; //0x6A = 8000		P5.25
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x0003; //0x6A = 3			P5.26
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x0096; //0x6A = 150		P5.27
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	programming.Program_Block_Data = 0x0003; //0x6A = 3			P5.28
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	return 0;
}
/*********************************************************************************************/

/********************************* RAMDAC Configuration **************************************/
double CMX7163_Set_RAM_DAC_Array(double voltage)
{
	int i ;
	if (voltage > 3.3)
		voltage = 3.3;
	if (voltage < 0.3)
		voltage = 0.3;

	voltage /= 3.3;
	voltage *= 1023;

	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0100; //0x6B = 0x0000	select idle mode
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	reg_done_select.Word_val = 0x0001; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);

	for (i = 1; i < 64 ; i++)
	{
		programming.Program_Block_Data = voltage * Sin_Table[i]; //0x6A = 0x0032 see table
		CMX7164_Write_WORD((CMX_WORD*) &programming);
		if (CMX7164_Check_Status(Reg_Done_Bit))
			return 1;
	}
	double tmp = (int) voltage;
	if (voltage > (tmp + 0.5) && (voltage + 1 <= 1023))
		voltage++;
	programming.Program_Block_Data = (int) voltage; //0x6A = 0x0032 see table
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; //0x6B = 0x0000	select idle mode
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	CMX7164_RAM_DAC_V = (voltage * 3.3) / 1023;
	return CMX7164_RAM_DAC_V;
}

/********************************* RAMDAC Configuration **************************************/
/*
 * CMX7164_RAM_DAC_RAMP_UP
 * CMX7164_RAM_DAC_RAMP_DOWN
 * CMX7164_RAM_DAC_NORMAL_OPERATION
 */
/********************************* RAMDAC Configuration **************************************/
int CMX7164_RAMDAC_Config(unsigned char mode)
{
	switch (mode)
	{
	case CMX7164_RAM_DAC_NORMAL_OPERATION:
		reg_done_select.Word_val = 0x0008; //69
		CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
		modem_mode_and_control.Word_val = 0x0000; //0x6B = 0x0000	select idle mode
		CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
		if (CMX7164_Check_Status(Reg_Done_Bit))
			return 1;

		reg_done_select.Word_val = 0x0001; //69
		CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
		programming.Program_Block_Data = 0x0032; //0x6A = 0x0032 see table
		CMX7164_Write_WORD((CMX_WORD*) &programming);
		if (CMX7164_Check_Status(Reg_Done_Bit))
			return 2;

		reg_done_select.Word_val = 0x0008; //69
		CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
		modem_mode_and_control.Word_val = 0x0750; //0x6B = 0x0750
		CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
		if (CMX7164_Check_Status(Reg_Done_Bit))
			return 4;

		reg_done_select.Word_val = 0x0001; //69
		CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
		programming.Program_Block_Data = 0x8000; //0x6A = 0x8000 Ramp up will start immidiatly after a Tx command is received
		CMX7164_Write_WORD((CMX_WORD*) &programming);
		if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
			return 5;
		programming.Program_Block_Data = 0x8000; //0x6A = 0x8000 Modulation will start immidiatly after a Tx command is received
		CMX7164_Write_WORD((CMX_WORD*) &programming);
		if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
			return 6;
		programming.Program_Block_Data = 0x8100; //0x6A = 0x800A Ramp down will start immidiatly after 0.5 symbol period TxEnd command is received
		CMX7164_Write_WORD((CMX_WORD*) &programming);
		if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
			return 7;

		aux_dac_0_control.Word_val = 0xC000;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_0_control); // AuxDAC enable and configure as RAMDAC
		break;
	case CMX7164_RAM_DAC_RAMP_UP:
		aux_dac_0_control.Word_val = 0xD000;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_0_control); // RAMDAC ramp up
		break;
	case CMX7164_RAM_DAC_RAMP_DOWN:
		aux_dac_0_control.Word_val = 0xE000;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_0_control); // RAMDAC ramp down
		break;
	}
	return 0;

}
/********************************** END RAMDAC Configuration *********************************/

/********************************** RX Enable ************************************************/
void CMX7164_RX_Enable(unsigned int enable)
{
	if (enable)
		gpio_control.Word_val |= 0x0F01;
	else
		gpio_control.Word_val &= 0x0F0E;
	CMX7164_Write_WORD((CMX_WORD*) &gpio_control);
}
/********************************* End RX Enable *********************************************/

/********************************** GPIO Configuration *********************************/
int CMX7164_GPIO_config(void)
{
	gpio_control.Word_val = 0x0F02; //GPIO RX_Gain D = 0 ,RX_EN C = 1
	CMX7164_Write_WORD((CMX_WORD*) &gpio_control);
	return 0;
}
/********************************* END GPIO Line Configuration ******************************/

/********************************** TX Enable ************************************************/
void CMX7164_Tx_Enable(unsigned char Enable)
{
	if (Enable == 1)
		gpio_set_gpio_pin(TXEN_OUTPUT_PIN);
	else
		gpio_clr_gpio_pin(TXEN_OUTPUT_PIN);
}
/********************************* End TX Enable *********************************************/

/********************************** Rx Shutdown **********************************************/
void CMX7164_Rx_SHDN(unsigned char Enable)
{
	if (Enable == 1)
		gpio_set_gpio_pin(TRANSCEIVER_SHDN_OUTPUT_PIN);
	else
		gpio_clr_gpio_pin(TRANSCEIVER_SHDN_OUTPUT_PIN);
}
/********************************* Rx Shutdown ***********************************************/

/********************************* RF Switch Control *****************************************/
void RF_Switch_Ctrl(unsigned char TX_RX)
{
	if (TX_RX == RF_SWITCH_RX)
		gpio_control.Word_val |= 0x0F02;
	else if (TX_RX == RF_SWITCH_TX)
		gpio_control.Word_val &= 0x0F0D;
	CMX7164_Write_WORD((CMX_WORD*) &gpio_control);
}
/***************************** End RF Switch Control *****************************************/

/******************************** Input / Output Filter Bandwidth Selection ******************/
/*
 INPUT_RRC_FILTER_25K			0x00
 INPUT_RRC_FILTER_50K			0x01
 INPUT_RRC_FILTER_100K			0x02
 INPUT_RRC_FILTER_200K			0x03

 OUTPUT_RRC_FILTER_12_5K			0x00
 OUTPUT_RRC_FILTER_25K			0x01
 OUTPUT_RRC_FILTER_50K			0x02
 OUTPUT_RRC_FILTER_100K			0x03
 */

void CMX7164_IO_Filter_Bendwidth_select(unsigned char input_filter,	unsigned char output_filter)
{
	//signal_control.Word_val = 0x10YZ
	signal_control.Word_val = 0x1000 |((((output_filter & 0x03) << 4) | ((output_filter & 0x03) << 6) | ((input_filter & 0x03) << 2)	| (input_filter & 0x03))& 0x0FFF);
	CMX7164_Write_WORD((CMX_WORD*) &signal_control);
}
/**************************** END Input / Output Filter Bandwidth Selection ******************/

/********************************* AGC configuration *****************************************/
void CMX7164_AGC_Config(void)
{
	signal_control.Word_val = 0x9000 | ((0xFFF) & 0x0FFF);		//AGC High Threshold
	CMX7164_Write_WORD((CMX_WORD*) &signal_control);

	signal_control.Word_val = 0xC000 | ((0x50) & 0x0FFF);		//AGC Signal Detect Timer reload
	CMX7164_Write_WORD((CMX_WORD*) &signal_control);

	signal_control.Word_val = 0x7000 | ((0x1F4) & 0x0FFF);		//AGC Low Timer
	CMX7164_Write_WORD((CMX_WORD*) &signal_control);

	signal_control.Word_val = 0xD000 | ((0x20) & 0x0FFF);		//AGC Signal Detect Timer Allow High Time
	CMX7164_Write_WORD((CMX_WORD*) &signal_control);

	agc_control.Word_val = 0x0010;
	CMX7164_Write_WORD((CMX_WORD*) &agc_control);
}
/*********************************** END AGC configuration ***********************************/

/***************************** SSOUT0 Port Configuration *************************************/
int CMX7164_SSOUT_Port_Config(void)
{
	modem_mode_and_control.Word_val = 0x0060; //0x6B = 0x0060
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);

	programming.Program_Block_Data = 0x0083; //0x6A = 0x0083
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;
	programming.Program_Block_Data = 0x0001; //0x6A = 0x0001		CLK = XTAL/4
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;
	programming.Program_Block_Data = 0x0002; //0x6A = 0x0002	Delay for 2.5 C-BUS bit periods between Frame syncs
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	modem_mode_and_control.Word_val = 0x0460; //0x6B = 0x0460
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);

	programming.Program_Block_Data = 0x0083; //0x6A = 0x0083
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;
	programming.Program_Block_Data = 0x0001; //0x6A = 0x0001		CLK = XTAL/4
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;
	programming.Program_Block_Data = 0x0002; //0x6A = 0x0002	Delay for 2.5 C-BUS bit periods between Frame syncs
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;

	modem_mode_and_control.Word_val = 0x0860; //0x6B = 0x0860
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);

	programming.Program_Block_Data = 0x0083; //0x6A = 0x0083
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;
	programming.Program_Block_Data = 0x0001; //0x6A = 0x0001		CLK = XTAL/4
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;
	programming.Program_Block_Data = 0x0002; //0x6A = 0x0002	Delay for 2.5 C-BUS bit periods between Frame syncs
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //wait until the value is registered
		return 1;
	return 0;
}
/********************************** END SSOUT1 Port Configuration ****************************/

/****************************** Preamble Tx (Test Mode)***************************************/
int CMX7164_Preamble_Tx(unsigned char Rump_up)
{
	reg_done_select.Word_val = 0x0002; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; // Flush FIFOs
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0082;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control); // Test - Preamble
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	if (Rump_up == 1)
	{
		aux_dac_0_control.Word_val = 0xD000;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_0_control);
		if (CMX7164_Check_Status(Ramp_Done_Bit))
			return 1;
	}
	else
	{
		aux_dac_0_control.Word_val = 0xE000;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_0_control);
		if (CMX7164_Check_Status(Ramp_Done_Bit))
			return 1;
	}
	return 0;
}
/****************************** Preamble Tx (Test Mode)***************************************/

/****************************** Deviation Tx (Test Mode)***************************************/
int CMX7164_Deviation_Tx(unsigned char Rump_up)
{
	/********************* GPIO INIT **************/
	/*	reg_done_select.Word_val = 0x0008 ;			//69
	 CMX7164_Write_WORD((CMX_WORD*)&reg_done_select);
	 modem_mode_and_control.Word_val = 0x0450;				//0x6B = 0x0450;
	 CMX7164_Write_WORD((CMX_WORD*)&modem_mode_and_control);
	 if(CMX7164_Check_Status(Reg_Done_Bit))
	 return 1 ;

	 reg_done_select.Word_val = 0x0001 ;			//69
	 CMX7164_Write_WORD((CMX_WORD*)&reg_done_select);
	 programming.Program_Block_Data = 0x0000;				//0x6A = 0xA000;
	 CMX7164_Write_WORD((CMX_WORD*)&programming);
	 if(CMX7164_Check_Status(Reg_Done_Bit))
	 return 1 ;
	 */
	/**********************************************/

	reg_done_select.Word_val = 0x0002; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; // Flush FIFOs
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0062;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control); // Test - Deviation
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	if (Rump_up == 1)
	{
		aux_dac_0_control.Word_val = 0xD000;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_0_control);
		if (CMX7164_Check_Status(Ramp_Done_Bit))
			return 1;
	}
	else
	{
		aux_dac_0_control.Word_val = 0xE000;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_0_control);
		if (CMX7164_Check_Status(Ramp_Done_Bit))
			return 1;
	}
	/*	if(CMX998_Initialize())
	 return 1;*/
	return 0;
}
/****************************** Deviation Tx (Test Mode)***************************************/

/*********************************************************************************************/

int CMX7164_Receive_Row_Data(unsigned char* data_buf, unsigned int byte_count)
{
	int i;
	int block_count;

	byte_count += byte_count % 15;
	block_count = byte_count / 15;
//	Row_receive_start:
	reg_done_select.Word_val = 0x0002; //69	set REG_DONE -> FLASH FIFO
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; //50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	modem_command_fifo_data_word.data = 0x1F00 | (block_count & 0xFF);// 49
	CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);

	CMX7164_Set_Interrupt_Source(Rx_FS_Det_Tx_Last_Tail_Bit);
	rx_tracking.Word_val = 0x0333;
	CMX7164_Write_WORD((CMX_WORD*) &rx_tracking);//66

	modem_mode_and_control.Word_val = 0x0401; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	CMX7164_Interrupt_Event = 0;

	vTaskSuspend(mac_task_handle);

	while (CMX7164_Interrupt_Event == 0)
	{
		if ((mac_state != MAC_RECEIVE) || (CMX7164_Reinit == 1))
		{
			CMX7164_Reinit = 0;
			CMX7164_Disable_Interrupt();
			return 2;
		}
/*		if (CMX7164_Reinit == 1)
		{
			CMX7164_Reinit = 0;
			goto Row_receive_start;
		}*/
	}
	MAC_Done = MAC_BUSY;

	fifo_control.Word_val = 0x0F00;
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	CMX7164_Set_Interrupt_Source(Rx_FIFO_Bit);
	CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level); //4F
	CMX7164_Interrupt_Event = 0;

	vTaskSuspend(mac_task_handle);

	CMX7164_Read_WORD((CMX_WORD*) &rx_fifo_data_word);//4D
	CMX7164_Read_WORD((CMX_WORD*) &rx_fifo_data_word);//4D

	if ((rx_fifo_data_word.data & 0x1F00) != 0x1F00)
		rx_fifo_data_word.data += 0;

	data_buf[0] = (rx_fifo_data_word.data & 0xFF);
	/*	CMX7164_Read_WORD((CMX_WORD *)&agc_gain_rssi);
	 CMX7164_Read_WORD((CMX_WORD *)&I_input_offset);
	 CMX7164_Read_WORD((CMX_WORD *)&Q_input_offset);
	 */
	//	printk("%02X",rx_fifo_data_word.data & 0xFF);

	for (i = 1; i < byte_count;)
	{
		do
		{
			CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level);
		} while (rx_fifo_level.data == 0);
		while ((rx_fifo_level.data != 0) && (i < byte_count))
		{
			if (i % 15 == 0)
			{
				CMX7164_Read_WORD((CMX_WORD*) &rx_fifo_data_word);//4D
				data_buf[i] = (rx_fifo_data_word.data & 0xFF);
			}
			else
			{
				CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_data_byte);
				data_buf[i] = rx_fifo_data_byte.data;
			}
			rx_fifo_level.data--;
			i++;
		}
		//i-- ;
		//		printk("%02X",data_buf[i]);
	}
	//	mac_input((unsigned char*)data_buf,block_size,0);
	/*	printk("   ");

	 print_average((short)frequency_error.Frequency_Error,(short)agc_gain_rssi.Word_val,
	 (short)I_input_offset.I_Q_DC_Offset_Applied_to_the_I_Q_INPUTs,
	 (short)Q_input_offset.I_Q_DC_Offset_Applied_to_the_I_Q_INPUTs);
	 printk(" %d  ",(short)frequency_error.Frequency_Error);
	 printk(" %X  ",(short)agc_gain_rssi.Word_val);
	 printk(" %d  ",(short)I_input_offset.I_Q_DC_Offset_Applied_to_the_I_Q_INPUTs);
	 printk(" %d  \r\n",(short)Q_input_offset.I_Q_DC_Offset_Applied_to_the_I_Q_INPUTs);
	 */

	CMX7164_Disable_Interrupt();
	CMX7164_Store_statistics();
	//	CMX7164_print_info();
	CMX7164_Frequency_fine_correction();
	CMX994_DC_Offset_Correction();

	modem_mode_and_control.Word_val = 0x0000; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);

	//	CMX7164_Check_Status(Reg_Done_Bit);

	//	cur_freq -= temp;
	//	LMX2541_Set_Frequency(cur_freq);
	return 0;
}

int CMX7164_Receive_PCC_frame(void)
{
	int i;
	unsigned char data[20];
	struct pcc_header *Pcc_Header;
	unsigned int bytes_left, block_count;
	unsigned short PCC_CRC_RX;
//Row_receive_start:
	reg_done_select.Word_val = 0x0002; //69	set REG_DONE -> FLASH FIFO
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; //50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	modem_command_fifo_data_word.data = 0x1A00 | (0x4);// 49
	CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);

	CMX7164_Set_Interrupt_Source(Rx_FS_Det_Tx_Last_Tail_Bit);
	rx_tracking.Word_val = 0x0333;
	CMX7164_Write_WORD((CMX_WORD*) &rx_tracking);//66

	modem_mode_and_control.Word_val = 0x0401; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	CMX7164_Interrupt_Event = 0;

	vTaskSuspend(mac_task_handle);

	while (CMX7164_Interrupt_Event == 0)
	{
		if ((mac_state != MAC_RECEIVE) || (CMX7164_Reinit == 1))
		{
			CMX7164_Reinit = 0;
			CMX7164_Disable_Interrupt();
			return 2;
		}
/*		if (CMX7164_Reinit == 1)
		{
			CMX7164_Reinit = 0;
			goto Row_receive_start;
		}*/
	}
	MAC_Done = MAC_BUSY;

	fifo_control.Word_val = 0x1400;
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	CMX7164_Set_Interrupt_Source(Rx_FIFO_Bit);
	CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level); //4F
	CMX7164_Interrupt_Event = 0;

	vTaskSuspend(mac_task_handle);

	CMX7164_Read_WORD((CMX_WORD*) &rx_fifo_data_word);//4D
	CMX7164_Read_WORD((CMX_WORD*) &rx_fifo_data_word);//4D

	data[0] = (rx_fifo_data_word.data & 0xFF);

	for (i = 1; i < 20;)
	{
		do
		{
			CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level);
		} while (rx_fifo_level.data == 0);
		while ((rx_fifo_level.data != 0) && (i < 20))
		{
			if (i % 10 == 0)
			{
				CMX7164_Read_WORD((CMX_WORD*) &rx_fifo_data_word);//4D
				data[i] = (rx_fifo_data_word.data & 0xFF);
			}
			else
			{
				CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_data_byte);
				data[i] = rx_fifo_data_byte.data;
			}
			rx_fifo_level.data--;
			i++;
		}
	}
	pcc_deinterleave(data, 20);

	PCC_CRC16(data, 18);
	PCC_CRC_RX = data[18] << 8 | data[19];
	if(PCC_CRC16(data, 18) != PCC_CRC_RX)
	{
		bytes_left = 0;
	}
	else
	{
		Pcc_Header = (struct pcc_header *) (&data[0]);
		bytes_left = ((unsigned int) (Pcc_Header->Data_bytes_number_high) << 8) | (unsigned int) (Pcc_Header->Data_bytes_number_low);
	}
	if (bytes_left <= 13)
	{
		mac_input(&data[5], bytes_left, 0);
		bytes_left = 0;

	}
	else
	{
		mac_input(&data[5], 13, 0);
		bytes_left -= 13;
		block_count = bytes_left / 18;

		if (bytes_left % 18)
			block_count++;

		while (block_count)
		{
			if (block_count != 1)
			{
				modem_command_fifo_data_word.data = 0x1A02;// 49
				CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);
			}

			fifo_control.Word_val = 0x1400;
			CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
			CMX7164_Set_Interrupt_Source(Rx_FIFO_Bit);
			CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level); //4F
			CMX7164_Interrupt_Event = 0;

			vTaskSuspend(mac_task_handle);

			for (i = 0; i < 20; i++)
			{
				CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_data_byte);
				data[i] = rx_fifo_data_byte.data;
			}
			pcc_deinterleave(data, 20);

			if (bytes_left > 18)
			{
				mac_input(&data[0], 18, 0);
				bytes_left -= 18;
			}
			else
			{
				mac_input(&data[0], bytes_left, 0);
				bytes_left = 0;
			}
			block_count--;
		}
	}
	CMX7164_Disable_Interrupt();
	CMX7164_Store_statistics();
	CMX7164_Frequency_fine_correction();
	CMX994_DC_Offset_Correction();

	modem_mode_and_control.Word_val = 0x0000; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	return 0;

}

/*********************************************************************************************/

/*********************************************************************************************/
int CMX7164_Receive_Intermediate_bloks(unsigned char* data, unsigned int size)
{
	int i;
	unsigned int byte_count = 0;
	unsigned int time_out;
	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	reg_done_select.Word_val = 0x0002; //69	set REG_DONE -> FLASH FIFO
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; //	@x50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	modem_command_fifo_data_word.data = 0x6000; //49 Itermediate block 15 byte
	CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);
	rx_tracking.Word_val = 0x0033; //66 Select auto tracking mode IQ DC corr. (see Table 4 3)
	CMX7164_Write_WORD((CMX_WORD*) &rx_tracking);
	modem_mode_and_control.Word_val = 0x0A01; // Rx search for Sync1 then Rx
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control); // Formatted Data


	while (CMX7164_Check_Status(Rx_FS_Det_Tx_Last_Tail_Bit))
		;
	while (byte_count < size)
	{
		CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level);//4F
		time_out = 100;
		while (rx_fifo_level.data < 15 && time_out != 0)
		{
			CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level);//4F
			time_out--;
			cpu_delay_us(100, FMCK_HZ);
		}
		if (time_out == 0)
			return 1;

		CMX7164_Read_WORD((CMX_WORD*) &rx_fifo_data_word);//4D

		for (i = 0; i < rx_fifo_level.data; i++)
		{
			CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_data_byte);
			data[byte_count] = rx_fifo_data_byte.data;
			byte_count++;
		}
	}
	CMX7164_Frequency_fine_correction();
	modem_mode_and_control.Word_val = 0x0000;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	return 0;
}
/*********************************************************************************************/

/*********************************************************************************************/
int CMX7164_Receive_MAC_Header(unsigned char* data,	unsigned char block_size_index)
{
	int i;
	unsigned int Block_Size_byte;
	if(CMX7164_Modulation_Type > 3)
		rx_tracking.Word_val = 0x0333; //66 Select auto tracking mode IQ DC corr. (see Table 4 3)
	else
		rx_tracking.Word_val = 0x0033; //66 Select auto tracking mode IQ DC corr. (see Table 4 3)
	CMX7164_Write_WORD((CMX_WORD*) &rx_tracking);
	Block_Size_byte = GetBlocSize(CMX7164_Modulation_Type);
//Receive_start:
	reg_done_select.Word_val = 0x0002; //69	set REG_DONE -> FLASH FIFO
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8000; //50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;

	CMX7164_Set_Block_Type(block_size_index, CMX7164_Modulation_Type);
	modem_command_fifo_data_byte.data = 0x00;
	CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_fifo_data_byte);
	CMX7164_Set_Interrupt_Source(Rx_FS_Det_Tx_Last_Tail_Bit);
	modem_mode_and_control.Word_val = 0x0A01; // Rx search for Sync1 then Rx
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control); // Formatted Data
	CMX7164_Interrupt_Event = 0;

	vTaskSuspend(mac_task_handle);

	while (CMX7164_Interrupt_Event == 0)
	{
		if ((mac_state != MAC_RECEIVE) || (CMX7164_Reinit == 1))
		{
			CMX7164_Reinit = 0;
			return 2;
		}
/*		if (CMX7164_Reinit == 1)
		{
			CMX7164_Reinit = 0;
			goto Receive_start;
		}*/
	}
	MAC_Done = MAC_BUSY;
	fifo_control.Word_val = (Block_Size_byte << 8) & 0x7F00; //50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	CMX7164_Set_Interrupt_Source(Rx_FIFO_Bit);
	CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level); //4F
	CMX7164_Interrupt_Event = 0;

	vTaskSuspend(mac_task_handle);

	CMX7164_Read_WORD((CMX_WORD*) &rx_fifo_data_word); //4D
	CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level); //4F
	for (i = 0; i < Block_Size_byte; i++)
	{
		CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_data_byte);
		data[i] = rx_fifo_data_byte.data;
	}
	CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level); //4F
	return 0;
}

int CMX7164_Receive_MAC_Payload(unsigned int size)
{
	unsigned int k, i = 0;
	unsigned char data[128];
	unsigned int Block_Size_byte = GetBlocSize(CMX7164_Modulation_Type);
	while (size)
	{
		//if(size - i > BlockSize[UsageBlockType])
		fifo_control.Word_val = (Block_Size_byte << 8) & 0x7F00; //50
		//else
		//	fifo_control.Word_val = ((unsigned short)(size - i) << 8) & 0x7F00 ;				//50
		CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
		CMX7164_Set_Interrupt_Source(Rx_FIFO_Bit);

		vTaskSuspend(mac_task_handle);

		CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_level); //4F
		if (rx_fifo_level.data)
		{
			for (k = 0; k < rx_fifo_level.data; k++)
			{
				CMX7164_Read_BYTE((CMX_BYTE*) &rx_fifo_data_byte);
				data[k] = rx_fifo_data_byte.data;
				i++;
				if (i == size)
				{
					k++;
					break;
				}
			}
			mac_input(data, k, 0);
			if (i == size)
				break;
		}
	}

	signal_control.Word_val = 0;
	CMX7164_Write_WORD((CMX_WORD*) &signal_control);

	CMX7164_Disable_Interrupt();
	CMX7164_Store_statistics();
	//	CMX7164_print_info();
	CMX7164_Frequency_fine_correction();
	CMX994_DC_Offset_Correction();
	//	modem_mode_and_control.Word_val = 0x0000 ;
	//	CMX7164_Write_WORD((CMX_WORD*)&modem_mode_and_control);
	return 0;
}
/*********************************************************************************************/

/*********************************************************************************************/
int CMX7164_Set_modulation_type_command(unsigned int modulation_type)
{
	int Image_loading = 0 ;
	if(modulation_type > 6 || modulation_type == 0)
		return -1 ;
	if(/**/((modulation_type > 3)&&(CMX7164_Modulation_Type >= 1)&&(CMX7164_Modulation_Type <= 3))/**/ ||
		((CMX7164_Modulation_Type > 3)&&(modulation_type >= 1)&&(modulation_type <= 3)) /**/ ||
		((modulation_type == 4 || modulation_type == 5)&& CMX7164_Modulation_Type == 6 )/**/||
		((CMX7164_Modulation_Type == 4 || CMX7164_Modulation_Type == 5)&& modulation_type == 6 )/**/)
	{
		Image_loading = 1 ;
	}
	ConfigRoot.G_Wireless.SG_Uhf.param_modulation = modulation_type;
	CMX7164_Modulation_Type = modulation_type ;
	if(Image_loading)
	{
		if(CMX7164_Initialize())
			return -1;
		CMX998_Set_Output_Power_dBm(ConfigRoot.G_Wireless.SG_Uhf.param_output_pow/2 , CMX_SET_WITH_ERR);
	}
	else
		CMX7164_Set_modulation_type(CMX7164_Modulation_Type);

	TC1_delay_us(10000);
	return 1;
}

/*********************************************************************************************/


/*********************************************************************************************/
/*
 CMX7164_MODULATION_TYPE_4QAM
 CMX7164_MODULATION_TYPE_16QAM
 CMX7164_MODULATION_TYPE_64QAM
 CMX7164_MODULATION_TYPE_2FSK
 CMX7164_MODULATION_TYPE_4FSK
 */
int CMX7164_Set_modulation_type(unsigned int modulation_type)
{
	reg_done_select.Word_val = 0x0008; //69	set REG_DONE -> Mode
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0240; //	@x6B=0x0240; 	go to idle mode with access to mod type
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //	while (@x7E & 0x4000 == 0); wait until the value is registered
		return -1;
	CMX7164_Modulation_Type = modulation_type;
	switch (modulation_type)
	{
	case 1:
		programming.Program_Block_Data = CMX7164_MODULATION_TYPE_4QAM;
		Network_Buffer_Size = NETWORK_BUFFER_SIZE_QAM ;
		CMX7164_Set_FEC();
		break;
	case 2:
		programming.Program_Block_Data = CMX7164_MODULATION_TYPE_16QAM;
		Network_Buffer_Size = NETWORK_BUFFER_SIZE_QAM ;
		CMX7164_Set_FEC();
		break;
	case 3:
		programming.Program_Block_Data = CMX7164_MODULATION_TYPE_64QAM;
		Network_Buffer_Size = NETWORK_BUFFER_SIZE_QAM ;
		CMX7164_Set_FEC();
		break;
	case 4:
		programming.Program_Block_Data = CMX7164_MODULATION_TYPE_2FSK;
		Network_Buffer_Size = NETWORK_BUFFER_SIZE_2FSK ;
		CMX7164_Set_FEC();
		break;
	case 5:
		programming.Program_Block_Data = CMX7164_MODULATION_TYPE_4FSK;
		Network_Buffer_Size = NETWORK_BUFFER_SIZE_4FSK ;
		CMX7164_Set_FEC();
		break;
	case 6:
		Network_Buffer_Size = NETWORK_BUFFER_SIZE_GMSK ;
		CMX7164_Set_FEC();
		//for GMSK FI-1 this field is reserved
		return -1;
		break;
	default:
		programming.Program_Block_Data = CMX7164_MODULATION_TYPE_4QAM;
		Network_Buffer_Size = NETWORK_BUFFER_SIZE_QAM ;
		CMX7164_Modulation_Type = 1;
		CMX7164_Set_FEC();
		break;
		/*	@x6A=modulation_type; modulation_type=
		 for FI-4 \4,16 or 64 QAM
		 for FI-2 \4 or 2 FSK
		 for FI-1 \reserved
		 */
	}
	reg_done_select.Word_val = 0x0001; //69	set REG_DONE -> PROG
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //	while (@x7E & 0x4000 == 0); wait until the value is registered
		return -1;
	return 1;
}
/*********************************************************************************************/

/*********************************************************************************************/
int CMX7164_set_Preamble_len(unsigned char len, unsigned char value)
{
	modem_mode_and_control.Word_val = 0x0030;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	programming.Program_Block_Data = ((len << 8) & 0xFF00) | (0x00FF & value);
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //	while (@x7E & 0x4000 == 0); wait until the value is registered
		return 1;
	return 0;
}
/*********************************************************************************************/

/*********************************************************************************************/
int CMX7164_set_FS_len(unsigned int len, unsigned short FS_data_0,unsigned short FS_data_1, unsigned short FS_data_2)
{
	modem_mode_and_control.Word_val = 0x0020;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	programming.Program_Block_Data = (len & 0x001F) | 0x2000;
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	programming.Program_Block_Data = FS_data_0 & 0xFFFF;
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	programming.Program_Block_Data = FS_data_1 & 0xFFFF;
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	programming.Program_Block_Data = FS_data_2 & 0xFFFF;
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //	while (@x7E & 0x4000 == 0); wait until the value is registered
		return 1;
	return 0;
}
/*********************************************************************************************/

/*********************************************************************************************/
int CMX7164_set_Teil_len(unsigned char len, unsigned short value)
{
	modem_mode_and_control.Word_val = 0x0130;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	programming.Program_Block_Data = ((len << 8) & 0xFF00) | (0x00FF & value);
	CMX7164_Write_WORD((CMX_WORD*) &programming);
	if (CMX7164_Check_Status(Reg_Done_Bit)) //	while (@x7E & 0x4000 == 0); wait until the value is registered
		return 1;
	return 0;
}
/*********************************************************************************************/

/*********************************************************************************************/
/*Block_Type = 0x05 , 0x06 , 0x07*/
/*Block_size = 0x00 - 0x0B*/

void CMX7164_Set_Block_Type(/*unsigned char Block_Type,*/unsigned char Block_size_index,unsigned char modulation)
{
	unsigned char temp = 5;
	switch (modulation)
	{
	case 1:
	case 2:
	case 3:
		temp = ((CMX7164_BLOCK_TYPE_INTERMEDIATE << 4) & 0xF0)
				| (Block_size_index & 0x0F);
		break;
	case 4:
		break;
	case 5:
		temp = ((CMX7164_BLOCK_TYPE_INTERMEDIATE << 4) & 0xF0)
				| (Block_size_index & 0x0F);
		break;
	case 6:
		temp = ((CMX7164_BLOCK_TYPE_INTERMEDIATE << 4) & 0xF0)
				| (Block_size_index & 0x0F);
		break;
	}
	modem_command_control_byte.data = temp;
	CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_control_byte);
}
/*********************************************************************************************/

/*********************************************************************************************/
void CMX7164_Invert_I_Q(void)
{
	reg_done_select.Word_val = 0x0008; //69	set REG_DONE -> Mode
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; // idle
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit)) // wait until the value is registered
		return;
	I_input_control.Word_val = 0x0400; //5f = 0x0801 ; I >> 180
	CMX7164_Write_WORD((CMX_WORD*) &I_input_control);
	Q_input_control.Word_val = 0x0C00; //60 = 0x0801 ; I >> 180
	CMX7164_Write_WORD((CMX_WORD*) &Q_input_control);
}
/*********************************************************************************************/

/*********************************************************************************************/
int CMX7164_Transmit_Servise_Block(unsigned char *data)
{
	unsigned int i, time_out;
	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	reg_done_select.Word_val = 0x0002; //69	set REG_DONE -> FLASH FIFO
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; //	@x50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	CMX7164_Set_Block_Type(0, CMX7164_Modulation_Type);
	for (i = 0; i < 15; i++)
	{
		modem_command_fifo_data_byte.data = data[i];
		CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_fifo_data_byte);
	}
	modem_command_fifo_data_word.data = 0xF000;
	CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);

	modem_mode_and_control.Word_val = 0x00A2;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	while (CMX7164_Check_Status(Rx_FS_Det_Tx_Last_Tail_Bit) && time_out > 0)
		;
	time_out--;
	if (time_out == 0)
		return 1;

	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	return 0;
}
/*********************************************************************************************/

/*********************************Transmit Row Data (Test)********************************/
int CMX7164_Transmit_Row_Data(unsigned char* data, int data_size)
{
	int i,data_index = 0, time_out;
	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	reg_done_select.Word_val = 0x0002; //69	set REG_DONE -> FLASH FIFO
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; //	@x50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	if (data_size > 15)
	{
		modem_command_control_byte.data = 0x1F; //4A
		CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_control_byte);
		for (i = 0; i < 15; i++)
		{
			modem_command_fifo_data_byte.data = data[i]; //48
			CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_fifo_data_byte);
			data_index++;
		}
		data_size -= 15;
		modem_mode_and_control.Word_val = 0x0042; //6b
		CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	}
	while (data_size > 15)
	{
		modem_command_control_byte.data = 0x1F; //4A
		CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_control_byte);
		for (i = 0; i < 15; i++)
		{
			modem_command_fifo_data_byte.data = data[data_index]; //48
			CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_fifo_data_byte);
			data_index++;
		}
		data_size -= 15;
	}

	modem_command_control_byte.data = 0x10 | (data_size & 0x0F); //4A
	CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_control_byte);
	for (i = 0; i < data_size; i++)
	{
		modem_command_fifo_data_byte.data = data[data_index]; //48
		CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_fifo_data_byte);
		data_index++;
	}
	modem_command_fifo_data_word.data = 0xF000; //49
	CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);
	if (data_size <= 15)
	{
		modem_mode_and_control.Word_val = 0x0042; //6b
		CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	}
	time_out = 100;
	while (CMX7164_Check_Status(Rx_FS_Det_Tx_Last_Tail_Bit) && time_out > 0)
		time_out--;

	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 2;
	if (time_out == 0)
		return 1;
	return 0;
}
/*********************************************************************************************/

/******************************Transmit Trimble frame Row Data *******************************/
int CMX7164_TX_Trim_Frame(unsigned char* data, unsigned int size)
{
	int i, time_out;
	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	reg_done_select.Word_val = 0x0002; //69	set REG_DONE -> FLASH FIFO
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; //	@x50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	modem_command_control_byte.data = 0x1F; //4A
	CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_control_byte);

	for (i = 0; i < 15; i++)
	{
		modem_command_fifo_data_byte.data = data[i]; //48
		CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_fifo_data_byte);
	}
	modem_command_fifo_data_word.data = 0xF000; //49
	CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);

	modem_mode_and_control.Word_val = 0x0042; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	time_out = 100;
	while (CMX7164_Check_Status(Rx_FS_Det_Tx_Last_Tail_Bit) && time_out > 0)
		time_out--;

	reg_done_select.Word_val = 0x0008; //69
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	modem_mode_and_control.Word_val = 0x0000; //6b
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 2;
	if (time_out == 0)
		return 1;
	return 0;
}
/*********************************************************************************************/

/*********************************************************************************************/
/*int CMX7164_Transmit_Intermediate_bloks(unsigned char* data , unsigned int size,unsigned char block_size)
 {
 int i ,j ;
 if(size%BlockSize[block_size])
 size+=BlockSize[block_size]-(size%BlockSize[block_size]);

 reg_done_select.Word_val = 0x0002 ;				//69	set REG_DONE -> FLASH FIFO
 CMX7164_Write_WORD((CMX_WORD*)&reg_done_select);
 fifo_control.Word_val = 0x0080 ;				//	@x50
 CMX7164_Write_WORD((CMX_WORD*)&fifo_control);
 if(CMX7164_Check_Status(Reg_Done_Bit))
 return 1;

 CMX7164_Set_Block_Type(CMX7164_BLOCK_TYPE_INTERMEDIATE , block_size) ;
 if(size > 10)
 {
 for(i = 0 ; i < 10 ; i++)
 {
 modem_command_fifo_data_byte.data = data[i];		//48
 CMX7164_Write_BYTE((CMX_BYTE*)&modem_command_fifo_data_byte);
 }
 }
 else
 {
 for(i = 0 ; i < size ; i++)
 {
 modem_command_fifo_data_byte.data = data[i];		//48
 CMX7164_Write_BYTE((CMX_BYTE*)&modem_command_fifo_data_byte);
 }
 modem_command_fifo_data_word.data = 0xF000 ;			//49
 CMX7164_Write_WORD((CMX_WORD*)&modem_command_fifo_data_word);
 }
 modem_mode_and_control.Word_val = 0x00A2 ;					//6B Tx
 //	modem_mode_and_control.Word_val = 0x00A6 ;					//6B Tx with DC Calibration
 CMX7164_Write_WORD((CMX_WORD*)&modem_mode_and_control);
 i = 10 ;
 while(i < size)
 {
 CMX7164_Read_BYTE((CMX_BYTE*)&modem_command_fifo_level);	//4B
 if(modem_command_fifo_level.data < 126 )
 {
 for(j = 0 ; j < (126-modem_command_fifo_level.data) ; j++)
 {
 modem_command_fifo_data_byte.data = data[i];	//48
 CMX7164_Write_BYTE((CMX_BYTE*)&modem_command_fifo_data_byte);
 i++;
 if(i >= size)
 break ;
 }
 }
 }

 if(size > 10)
 {
 modem_command_fifo_data_word.data = 0xF000 ;			//49
 CMX7164_Write_WORD((CMX_WORD*)&modem_command_fifo_data_word);
 }

 //	CMX7164_Read_WORD((CMX_WORD*)&irq_status);
 //	CMX7164_Set_Interrupt_Source(Rx_FS_Det_Tx_Last_Tail_Bit);
 //	vTaskSuspend( mac_task_handle );
 //	CMX7164_Disable_Interrupt();

 CMX7164_TimeOut = TC1_Get_us();
 while(CMX7164_Check_Status(Rx_FS_Det_Tx_Last_Tail_Bit) && (int)(TC1_Get_us() - CMX7164_TimeOut < 1000000));

 if(TC1_Get_us() - CMX7164_TimeOut >= 1000000)
 return 2 ;
 //	reg_done_select.Word_val = 0x0008 ;			//69
 //	CMX7164_Write_WORD((CMX_WORD*)&reg_done_select);
 //	modem_mode_and_control.Word_val = 0x0000 ;				//6B
 //	CMX7164_Write_WORD((CMX_WORD*)&modem_mode_and_control);
 //	if(CMX7164_Check_Status(Reg_Done_Bit))
 //		return 3;
 return 0;
 }*/
/*********************************************************************************************/

/*********************************************************************************************/
int CMX7164_Transmit_Intermediate_bloks(unsigned char* data, unsigned int size,	unsigned char block_size_index)
{
	int i, j;
	//	unsigned char data_tmp;
	unsigned int Addition, Block_Size_byte = GetBlocSize(
			CMX7164_Modulation_Type);
	if (size % Block_Size_byte)
	{
		Addition = Block_Size_byte - (size % Block_Size_byte);
		size += Block_Size_byte - (size % Block_Size_byte);
	}
	CMX7164_Disable_Interrupt();

	reg_done_select.Word_val = 0x0002; //69	set REG_DONE -> FLASH FIFO
	CMX7164_Write_WORD((CMX_WORD*) &reg_done_select);
	fifo_control.Word_val = 0x8080; //50
	CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
	if (CMX7164_Check_Status(Reg_Done_Bit))
		return 1;
	CMX7164_Set_Block_Type(block_size_index, CMX7164_Modulation_Type);
	if (size > 10)
	{
		for (i = 0; i < 10; i++)
		{
			modem_command_fifo_data_byte.data = data[i]; //48
			CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_fifo_data_byte);
		}
	}
	else
	{
		for (i = 0; i < size; i++)
		{
			modem_command_fifo_data_byte.data = data[i]; //48
			CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_fifo_data_byte);
		}
		modem_command_fifo_data_word.data = 0xF000; //49
		CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);
	}
	modem_mode_and_control.Word_val = 0x00A2; //6B Tx
	//	modem_mode_and_control.Word_val = 0x00A6 ;					//6B Tx with DC Calibration
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	i = 10;
	while (i < size)
	{
		CMX7164_Read_BYTE((CMX_BYTE*) &modem_command_fifo_level); //4B
		if (modem_command_fifo_level.data < 50)
		{
			for (j = 0; j < (50 - modem_command_fifo_level.data); j++)
			{
				/*				if((i % Block_Size_byte) == 0)
				 {
				 modem_command_fifo_data_word.data = (((CMX7164_BLOCK_TYPE_INTERMEDIATE << 12)& 0xF000) |((block_size << 8) & 0x0F00) ) | data[i];
				 CMX7164_Write_WORD((CMX_WORD*)&modem_command_fifo_data_word);
				 }
				 else
				 {
				 */modem_command_fifo_data_byte.data = data[i]; //48
				CMX7164_Write_BYTE((CMX_BYTE*) &modem_command_fifo_data_byte);
				//				}
				i++;
				if (i >= size)
					break;
				//				TC1_delay_us(100);
			}
			//			printk("%d\n\r",modem_command_fifo_level.data);
		}
		//		TC1_delay_us(5000);
	}

	if (size > 10)
	{
		modem_command_fifo_data_word.data = 0xF000; //49
		CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);
	}

	/*	CMX7164_Read_WORD((CMX_WORD*)&irq_status);
	 CMX7164_Set_Interrupt_Source(Rx_FS_Det_Tx_Last_Tail_Bit);

	 vTaskSuspend( mac_task_handle );

	 CMX7164_Disable_Interrupt();*/

	CMX7164_TimeOut = TC1_Get_us();
	while (CMX7164_Check_Status(Rx_FS_Det_Tx_Last_Tail_Bit)	&& (int) (TC1_Get_us() - CMX7164_TimeOut < 1000000))
		;

	if (TC1_Get_us() - CMX7164_TimeOut >= 1000000)
		return 2;
	//	reg_done_select.Word_val = 0x0008 ;			//69
	//	CMX7164_Write_WORD((CMX_WORD*)&reg_done_select);
	//	modem_mode_and_control.Word_val = 0x0000 ;				//6B
	//	CMX7164_Write_WORD((CMX_WORD*)&modem_mode_and_control);
	//	if(CMX7164_Check_Status(Reg_Done_Bit))
	//		return 3;
	return 0;
}
/*********************************************************************************************/

/*******************************************Image loading ************************************/
int CMX7164_Image_loading(unsigned short modulation_type)
{
	unsigned char load_buffer[256];
	unsigned char read_buff;
	unsigned int i, j, timeout;
	unsigned char write_buf[4];

	unsigned int IMAGE_DB1_LEN;
	unsigned int IMAGE_DB1_PTR;
	unsigned int IMAGE_DB1_CHK_HI;
	unsigned int IMAGE_DB1_CHK_LO;
	unsigned int IMAGE_DB2_LEN;
	unsigned int IMAGE_DB2_PTR;
	unsigned int IMAGE_DB2_CHK_HI;
	unsigned int IMAGE_DB2_CHK_LO;
	unsigned int IMAGE_VERSION;

	struct file_t CMX_File;
	if (modulation_type == CMX7164_QAM_MODULATION)
	{
		IMAGE_DB1_LEN = CMX7164_IMAGE_QAM_DB1_LEN;
		IMAGE_DB1_PTR = CMX7164_IMAGE_QAM_DB1_PTR;
		IMAGE_DB1_CHK_HI = CMX7164_IMAGE_QAM_DB1_CHK_HI;
		IMAGE_DB1_CHK_LO = CMX7164_IMAGE_QAM_DB1_CHK_LO;

		IMAGE_DB2_LEN = CMX7164_IMAGE_QAM_DB2_LEN;
		IMAGE_DB2_PTR = CMX7164_IMAGE_QAM_DB2_PTR;
		IMAGE_DB2_CHK_HI = CMX7164_IMAGE_QAM_DB2_CHK_HI;
		IMAGE_DB2_CHK_LO = CMX7164_IMAGE_QAM_DB2_CHK_LO;
		IMAGE_VERSION = CMX7164_IMAGE_QAM_VERSION;
		find_file(&CMX_File, "CMXDB4_1");
	}
	else if (modulation_type == CMX7164_FSK_MODULATION)
	{
		IMAGE_DB1_LEN = CMX7164_IMAGE_FSK_DB1_LEN;
		IMAGE_DB1_PTR = CMX7164_IMAGE_FSK_DB1_PTR;
		IMAGE_DB1_CHK_HI = CMX7164_IMAGE_FSK_DB1_CHK_HI;
		IMAGE_DB1_CHK_LO = CMX7164_IMAGE_FSK_DB1_CHK_LO;

		IMAGE_DB2_LEN = CMX7164_IMAGE_FSK_DB2_LEN;
		IMAGE_DB2_PTR = CMX7164_IMAGE_FSK_DB2_PTR;
		IMAGE_DB2_CHK_HI = CMX7164_IMAGE_FSK_DB2_CHK_HI;
		IMAGE_DB2_CHK_LO = CMX7164_IMAGE_FSK_DB2_CHK_LO;
		IMAGE_VERSION = CMX7164_IMAGE_FSK_VERSION;
		find_file(&CMX_File, "CMXDB2_1");
	}
	else if (modulation_type == CMX7164_GMSK_MODULATION)
	{
		IMAGE_DB1_LEN = CMX7164_IMAGE_GMSK_DB1_LEN;
		IMAGE_DB1_PTR = CMX7164_IMAGE_GMSK_DB1_PTR;
		IMAGE_DB1_CHK_HI = CMX7164_IMAGE_GMSK_DB1_CHK_HI;
		IMAGE_DB1_CHK_LO = CMX7164_IMAGE_GMSK_DB1_CHK_LO;

		IMAGE_DB2_LEN = CMX7164_IMAGE_GMSK_DB2_LEN;
		IMAGE_DB2_PTR = CMX7164_IMAGE_GMSK_DB2_PTR;
		IMAGE_DB2_CHK_HI = CMX7164_IMAGE_GMSK_DB2_CHK_HI;
		IMAGE_DB2_CHK_LO = CMX7164_IMAGE_GMSK_DB2_CHK_LO;
		IMAGE_VERSION = CMX7164_IMAGE_GMSK_VERSION;
		find_file(&CMX_File, "CMXDB1_1");
	}

	//DB1 loading
	read_buff = 0;
	CMX7164_SPI_Write(0x01, write_buf, 0);

	timeout = 1000;
	while (read_buff != 3 && --timeout) //while(@x4F != 3){}; wait for 3 check words
		CMX7164_SPI_Read(0x4f, &read_buff, 1);
	if (timeout == 0)
		return 1;
	for (i = 0; i < 3; i++) //for(i=0;i<3;i++) temp=@x4D;
		CMX7164_SPI_Read(0x4d, write_buf, 2);

	write_buf[1] = IMAGE_DB1_LEN & 0xFF; //@x49=DB1_len;
	write_buf[0] = IMAGE_DB1_LEN >> 8; //@x49=DB1_len;
	CMX7164_SPI_Write(0x49, write_buf, 2);

	write_buf[1] = IMAGE_DB1_PTR & 0xFF; //@x49=DB1_ptr;
	write_buf[0] = IMAGE_DB1_PTR >> 8; //@x49=DB1_ptr;
	CMX7164_SPI_Write(0x49, write_buf, 2);

	for (i = 0; i < IMAGE_DB1_LEN; i += 128)
	{
		at25dfx_read_sector((CMX_File.sector_number + (i >> 7)), 1, load_buffer);

		read_buff = 1;
		timeout = 1000;
		while (read_buff != 0 && timeout--) //while(@x4B != 0){};
			if (CMX7164_SPI_Read(0x4B, &read_buff, 1))
				return 1;
		if (timeout == 0)
			return 1;

		for (j = 0; (j < 256) && ((i * 2 + j) < (IMAGE_DB1_LEN * 2)); j += 2)
			CMX7164_SPI_Write(0x49, &load_buffer[j], 2);
	}
	CMX7164_SPI_Read(0x4d, write_buf, 2);
	CMX7164_SPI_Read(0x4d, &write_buf[2], 2);

	if ((write_buf[0] != (IMAGE_DB1_CHK_HI >> 8)) || (write_buf[1]!= (IMAGE_DB1_CHK_HI & 0xff)) || (write_buf[2] != (IMAGE_DB1_CHK_LO >> 8)) || (write_buf[3] != (IMAGE_DB1_CHK_LO & 0xff)))
		return 1;
	//DB2 loading

	if (modulation_type == CMX7164_QAM_MODULATION)
		find_file(&CMX_File, "CMXDB4_2");
	else if (modulation_type == CMX7164_FSK_MODULATION)
		find_file(&CMX_File, "CMXDB2_2");
	else if (modulation_type == CMX7164_GMSK_MODULATION)
		find_file(&CMX_File, "CMXDB1_2");

	write_buf[1] = IMAGE_DB2_LEN & 0xFF; //@x49=DB2_len;
	write_buf[0] = IMAGE_DB2_LEN >> 8; //@x49=DB2_len;
	CMX7164_SPI_Write(0x49, write_buf, 2);

	write_buf[1] = IMAGE_DB2_PTR & 0xFF; //@x49=DB2_ptr;
	write_buf[0] = IMAGE_DB2_PTR >> 8; //@x49=DB2_ptr;
	CMX7164_SPI_Write(0x49, write_buf, 2);

	for (i = 0; i < IMAGE_DB2_LEN; i += 128)
	{
		at25dfx_read_sector((CMX_File.sector_number + (i >> 7)), 1, load_buffer);
		read_buff = 1;
		timeout = 1000;
		while (read_buff != 0 && timeout--) //while(@x4B != 0){};
			if (CMX7164_SPI_Read(0x4B, &read_buff, 1))
				return 1;
		if (timeout == 0)
			return 1;

		for (j = 0; (j < 256) && ((i * 2 + j) < (IMAGE_DB2_LEN * 2)); j += 2)
			CMX7164_SPI_Write(0x49, &load_buffer[j], 2);
	}

	CMX7164_SPI_Read(0x4d, write_buf, 2);
	CMX7164_SPI_Read(0x4d, &write_buf[2], 2);

	if ((write_buf[0] != (IMAGE_DB2_CHK_HI >> 8)) || (write_buf[1]!= (IMAGE_DB2_CHK_HI & 0xff)) || (write_buf[2] != (IMAGE_DB2_CHK_LO >> 8)) || (write_buf[3] != (IMAGE_DB2_CHK_LO & 0xff)))
		return 1;

	//ACTIVATE
	write_buf[1] = CMX7164_IMAGE_ACTIVATE_LEN & 0xff; //@x49=ACTIVATE_len;
	write_buf[0] = CMX7164_IMAGE_ACTIVATE_LEN >> 8; //@x49=ACTIVATE_len;
	CMX7164_SPI_Write(0x49, write_buf, 2);

	write_buf[1] = CMX7164_IMAGE_ACTIVATE_PTR & 0xff; //@x49=ACTIVATE_ptr;
	write_buf[0] = CMX7164_IMAGE_ACTIVATE_PTR >> 8; //@x49=ACTIVATE_ptr;
	CMX7164_SPI_Write(0x49, write_buf, 2);

	write_buf[0] = 0xAA;
	write_buf[1] = 0xAA;
	timeout = 1000;
	while (((write_buf[0] & 0x40) != 0x40) && timeout--) //while(@x7E !& 0x4000){};
		if (CMX7164_SPI_Read(0x7E, write_buf, 2))
			return 1;
	if (timeout == 0)
		return 1;

	CMX7164_SPI_Read(0x4D, write_buf, 2);
	CMX7164_SPI_Read(0x4D, &write_buf[2], 2);
	if ((write_buf[0] != (CMX7164_IMAGE_ID >> 8)) || (write_buf[1] != (CMX7164_IMAGE_ID & 0xff)) || (write_buf[2] != (IMAGE_VERSION >> 8)) || (write_buf[3] != (IMAGE_VERSION & 0xff)))
		return 1;

	return 0;
}
/************************************End of Image loading ************************************/

/************************** Transmission DC Offset Calibration ********************************/
int CMX7164_TX_DC_Offset_Calibration(void)
{
	int I_s, Q_s, i, IREF, QREF, IDC, QDC, d;

	modem_mode_and_control.Word_val = 0x0A01;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
	CMX_delay(50);

	modem_mode_and_control.Word_val = 0x0000;
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);

	/*	signal_control.Word_val = 0x1800 ;
	 CMX7164_Write_WORD((CMX_WORD*)&signal_control);
	 I_Q_output_config.Word_val = 0xAC22 ;
	 CMX7164_Write_WORD((CMX_WORD*)&I_Q_output_config);
	 */
	CMX_delay(50);
	// I DC OFFSET

	aux_dac_1_control.Word_val = 0x8000; // 5A SET DAC1=0
	CMX7164_Write_WORD((CMX_WORD*) &aux_dac_1_control);
	CMX_delay(5);
	CMX998_Write(0x02, 0xFD); // ERROR GAIN=1, LOOP CLOSE
	CMX_delay(5);
	CMX998_Write(0x07, 0x81); // DCMEAS CONNECT TO IREF
	CMX7164_Read_WORD((CMX_WORD*) &irq_status);
	aux_adc_1_control.Word_val = 0x8900; // 52 ENABLE ADC1
	CMX7164_Write_WORD((CMX_WORD*) &aux_adc_1_control);
	if (CMX7164_Check_Status(Aux_ADC1_Bit))
		return 31;
	CMX7164_Read_WORD((CMX_WORD*) &aux_adc_1_read); //72 Read IREF
	IREF = aux_adc_1_read.Word_val;
	CMX_delay(5);
	CMX998_Write(0x07, 0x82); // DCMEAS CONNECT TO IDC (error amplifier gain K=1)
	I_s = 0;
	i = 0;

	while (i < 100)
	{
		CMX_delay(5);
		aux_dac_1_control.Word_val = 0x8000 | I_s; //5A SET DAC1=s
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_1_control);
		CMX7164_Read_WORD((CMX_WORD*) &irq_status);
		if (CMX7164_Check_Status(Aux_ADC1_Bit))
			return 32;
		CMX7164_Read_WORD((CMX_WORD*) &aux_adc_1_read); // 72 COM1>> IDC
		IDC = aux_adc_1_read.Word_val;
		d = IREF - IDC;
		if (d == 0)
			break;
		I_s = I_s - d;
		if (I_s > 1023)
			I_s = 0x3FF;
		i++;
	}
	if (d != 0)
		return 33;
	/*if (i==100)
	 {
	 CMX_delay(5);
	 aux_dac_1_control.Word_val = 0x81FF ; //5A SET DAC1=1FF
	 CMX7164_Write_WORD((CMX_WORD*)&aux_dac_1_control);
	 }*/
	// Q DC OFFSET
	CMX_delay(5);
	aux_dac_2_control.Word_val = 0x8000; //5B SET DAC2=0
	CMX7164_Write_WORD((CMX_WORD*) &aux_dac_2_control);

	CMX_delay(5);
	CMX998_Write(0x07, 0x80); // DCMEAS CONNECT TO Qref
	CMX_delay(50);
	CMX7164_Read_WORD((CMX_WORD*) &irq_status);
	if (CMX7164_Check_Status(Aux_ADC1_Bit))
		return 34;
	CMX7164_Read_WORD((CMX_WORD*) &aux_adc_1_read);
	QREF = aux_adc_1_read.Word_val;
	CMX_delay(5);
	CMX998_Write(0x07, 0x83); // DCMEAS CONNECT TO Qdc
	Q_s = 0;
	i = 0;
	while (i < 100)
	{
		CMX_delay(5);
		aux_dac_2_control.Word_val = 0x8000 | Q_s;// SET DAC2=s
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_2_control);
		CMX_delay(10);
		CMX7164_Read_WORD((CMX_WORD*) &irq_status);
		if (CMX7164_Check_Status(Aux_ADC1_Bit))
			return 35;
		CMX7164_Read_WORD((CMX_WORD*) &aux_adc_1_read);
		QDC = aux_adc_1_read.Word_val;
		d = QREF - QDC;
		if (d == 0)
			break;
		Q_s = Q_s - d;

		Q_s &= 0x3FF;
		i++;
	}
	if (d != 0)
		return 36;
	/*	if (i==100)
	 {
	 CMX_delay(5);
	 aux_dac_2_control.Word_val = 0x81FF ; //5B SET DAC1=1FF
	 CMX7164_Write_WORD((CMX_WORD*)&aux_dac_2_control);
	 }
	 */
	CMX998_Write(0x02, 0xFC); // ERROR GAIN=100, LOOP CLOSE
	// I DC OFFSET
	CMX_delay(5);
	CMX998_Write(0x07, 0x82); // DCMEAS CONNECT TO IDC
	i = 0;

	while (i < 5)
	{
		CMX_delay(10);
		CMX7164_Read_WORD((CMX_WORD*) &irq_status);
		if (CMX7164_Check_Status(Aux_ADC1_Bit))
			return 37;
		CMX7164_Read_WORD((CMX_WORD*) &aux_adc_1_read); // 72 COM1>> IDC
		IDC = aux_adc_1_read.Word_val;
		I_s -= (IREF - IDC) / 8;
		CMX_delay(5);
		aux_dac_1_control.Word_val = 0x8000 | I_s; //5A SET DAC1=s
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_1_control);
		i++;
	}

	while (i < 100)
	{
		CMX_delay(10);
		CMX7164_Read_WORD((CMX_WORD*) &irq_status);
		if (CMX7164_Check_Status(Aux_ADC1_Bit))
			return 38;
		CMX7164_Read_WORD((CMX_WORD*) &aux_adc_1_read); // 72 COM1>> IDC
		IDC = aux_adc_1_read.Word_val;
		d = IREF - IDC;
		if ((d >= -1) && (d <= 1))
			//if(d ==0)
			break;
		if (d >= 0)
		{
			I_s--;
		}
		else
		{
			I_s++;
		}
		I_s &= 0x3FF;
		CMX_delay(5);
		aux_dac_1_control.Word_val = 0x8000 | I_s; //5A SET DAC1=s
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_1_control);
		i++;
	}
	/*	if (i==100)
	 {
	 CMX_delay(5);
	 aux_dac_1_control.Word_val = 0x81FF ; //5A SET DAC1=1FF
	 CMX7164_Write_WORD((CMX_WORD*)&aux_dac_1_control);
	 }
	 */
	if ((d < -1) && (d > 1))
		return 39;
	// Q DC OFFSET

	CMX_delay(5);
	CMX998_Write(0x07, 0x83); // DCMEAS CONNECT TO Qdc
	i = 0;

	while (i < 5)
	{
		CMX_delay(10);
		CMX7164_Read_WORD((CMX_WORD*) &irq_status);
		if (CMX7164_Check_Status(Aux_ADC1_Bit))
			return 310;
		CMX7164_Read_WORD((CMX_WORD*) &aux_adc_1_read); // 72 COM1>> IDC
		QDC = aux_adc_1_read.Word_val;
		Q_s -= (QREF - QDC) / 8;
		CMX_delay(5);
		aux_dac_2_control.Word_val = 0x8000 | Q_s; //5A SET DAC1=s
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_2_control);
		i++;
	}

	while (i < 100)
	{
		CMX_delay(10);
		CMX7164_Read_WORD((CMX_WORD*) &irq_status);
		if (CMX7164_Check_Status(Aux_ADC1_Bit))
			return 311;
		CMX7164_Read_WORD((CMX_WORD*) &aux_adc_1_read);
		QDC = aux_adc_1_read.Word_val;
		d = QREF - QDC;
		if ((d >= -1) && (d <= 1))
			//if(d == 0)
			break;
		if (d >= 0)
		{
			Q_s--;
		}
		else
		{
			Q_s++;
		}
		Q_s &= 0x3FF;
		CMX_delay(5);
		aux_dac_2_control.Word_val = 0x8000 | Q_s;// SET DAC2=s
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_2_control);
		i++;
	}
	if ((d < -1) && (d > 1))
		return 312;
	/*
	 * {
	 CMX_delay(5);
	 aux_dac_2_control.Word_val = 0x81FF ; //5B SET DAC1=1FF
	 CMX7164_Write_WORD((CMX_WORD*)&aux_dac_2_control);
	 }*/

	CMX998_Write(0x07, 0x80);
	CMX998_Write(0x02, 0xFC);

	return 0;

	//	CMX998_Power_Down();
}

void CMX7164_TX_DC_Offset_Correction(unsigned short output_power_dbm_05)
{
	int k = output_power_dbm_05;
	if (k / 2 < 25)
		return;
	if (k / 2 < 28)
	{
		aux_dac_1_control.Word_val += 40;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_1_control);
		aux_dac_2_control.Word_val += 40;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_2_control);
		return;
	}
	if (k / 2 < 30)
	{
		aux_dac_1_control.Word_val += 60;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_1_control);
		aux_dac_2_control.Word_val += 60;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_2_control);
		return;
	}
	if (k / 2 <= 33)
	{
		aux_dac_1_control.Word_val += 70;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_1_control);
		aux_dac_2_control.Word_val += 70;
		CMX7164_Write_WORD((CMX_WORD*) &aux_dac_2_control);
		return;
	}
}
/************************* End Transmission DC Offset Calibration ******************************/

/*************************************Coarse frequency correction************************************/
int CMX7164_Search_Frequency(unsigned int correction_offset_khz)
{
	unsigned char correction_done = 1;
	short freq_err;
	unsigned int correction_offset_khz_temp = correction_offset_khz - 1;
	char direction = 0;
	Timer_Tik freq_correct_tick;
	while ((correction_done == 1) && (correction_offset_khz_temp != 0))
	{
		fifo_control.Word_val = 0x8000; //@x50=0x8000;	// Flush FIFO
		CMX7164_Write_WORD((CMX_WORD*) &fifo_control);
		modem_command_fifo_data_word.data = 0x600F; //@x49=0x600F;	// Itermediate block 15 byte
		CMX7164_Write_WORD((CMX_WORD*) &modem_command_fifo_data_word);
		rx_tracking.Word_val = 0x0033; //@x66=0x0033;	// Select auto tracking mode IQ DC corr. (see Table 4 3)
		CMX7164_Write_WORD((CMX_WORD*) &rx_tracking);
		modem_mode_and_control.Word_val = 0x0C01; //$x6B=0x0C01; 	// Rx with auto modulation type detection for
		CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control); // Formatted Data


		freq_correct_tick = TC1_Get_us();
		while (TC1_IF_us(freq_correct_tick, 1000))
		{
			if (!CMX7164_Check_Status(Rx_FIFO_Bit)) // wait Service block is ready
			{
				correction_done = 0;
				break;
			}
		}
		if (correction_done)
		{
			if (direction == 1)
			{
				direction = 0;
				LMX2541_Frequency += (correction_offset_khz	- correction_offset_khz_temp) * 1000;
			}
			else
			{
				direction = 1;
				LMX2541_Frequency -= (correction_offset_khz	- correction_offset_khz_temp) * 1000;
			}
			correction_offset_khz_temp--;
			if (LMX2541_Set_Frequency(LMX2541_Frequency * 2) < 0)
				return 2;
		}
	}

	CMX7164_Read_WORD((CMX_WORD*) &frequency_error);
	freq_err = (short) frequency_error.Frequency_Error;
	if ((freq_err > -50) && (freq_err < 50))
		return 1;
	LMX2541_Frequency -= freq_err;
	if (LMX2541_Set_Frequency(LMX2541_Frequency * 2) < 0)
		return 2;

	return !correction_done;
}
/********************************End of Coarse frequency correction**********************************/
/*void sort_matrix(short * values, unsigned int length)
 {
 int i,j,minn;
 short min,a;
 for (j=0; j<length; j++)
 {
 min=50;
 minn=0;
 for(i=j; i<length; i++)
 {
 if(min>values[i])
 {
 min=values[i];
 minn=i;
 }
 }
 a=values[minn];
 values[minn]= values[j];
 values[j]=a;
 }
 }*/

void sort_matrix(short * values, unsigned int length)
{
	int i, j, ind;
	short temp, a;
	for (i = 0; i < length; i++)
	{
		temp = values[i];
		ind = i;
		for (j = i; j < length; j++)
		{
			if (temp > values[j])
			{
				temp = values[j];
				ind = j;
			}
		}
		a = values[i];
		values[i] = temp;
		values[ind] = a;
	}
}

short find_middle_value(void)
{
	short temp[FREQ_MATRIX_SIZE];
	unsigned int i, result = 0;
	for (i = 0; i < FREQ_MATRIX_SIZE; i++)
		temp[i] = freq_err_val[i];
	sort_matrix(&temp[0], FREQ_MATRIX_SIZE);
	for (i = ACTUAL_CYCLE_START; i < ACTUAL_CYCLE_START	+ ACTUAL_FREQ_MATRIX_SIZE; i++)
		result += temp[i];
	result >>= 2;
	return result;
}

/*************************************Fine frequency correction************************************/
void CMX7164_Frequency_fine_correction(void)
{
	short freq_err, i;
	CMX7164_Read_WORD((CMX_WORD*) &frequency_error);
	freq_err_val[freq_err_val_index % FREQ_MATRIX_SIZE]	= (short) frequency_error.Frequency_Error;
	freq_err_val_index++;

	freq_err = find_middle_value();
	if ((freq_err > -MAX_FREQ_ERROR) && (freq_err < MAX_FREQ_ERROR))
		return;
	LMX2541_Frequency -= freq_err;
	if (LMX2541_Set_Frequency(LMX2541_Frequency * 2) < 0)
		return;
	for (i = 0; i < FREQ_MATRIX_SIZE; i++)
		freq_err_val[i] = 0;
}
/*************************************Fine frequency correction************************************/
unsigned int fs_count = 0;
void CMX7164_print_info(void)
{
	printk("\r\n----------------------------------\r\n");
	CMX7164_Read_WORD((CMX_WORD*) &agc_gain_rssi);
	printk("AGC gain = %d   ", (agc_gain_rssi.Word_val >> 12) & 0x0F);
	printk("RSSI = %d   ", (short) (agc_gain_rssi.Word_val << 4) / 16);

	CMX7164_Read_WORD((CMX_WORD*) &frequency_error);
	printk("Freq_err =  %d Hz   ", (short) frequency_error.Frequency_Error);

	signal_control.Word_val = 0x0000;
	CMX7164_Write_WORD((CMX_WORD*) &signal_control);
	CMX7164_Read_WORD((CMX_WORD *) &I_input_offset);
	CMX7164_Read_WORD((CMX_WORD *) &Q_input_offset);
	printk("I_DC =  %d mV   ",(short) I_input_offset.I_Q_DC_Offset_Applied_to_the_I_Q_INPUTs * 1000 / 65535);
	printk("Q_DC =  %d mV   ",(short) Q_input_offset.I_Q_DC_Offset_Applied_to_the_I_Q_INPUTs * 1000 / 65535);
	fs_count++;
	printk("FS = %d\r\n", fs_count);
}
/*********************************************************************************************/

/*********************************************************************************************/
double CMX7164_GET_EVM(void)
{
	double rx_error_magnitude_tmp, EVM_Temp;
	CMX7164_Read_WORD((CMX_WORD*) &rx_error_magnitude);
	rx_error_magnitude_tmp = rx_error_magnitude.Rx_Error_Magnitude;
	switch (ConfigRoot.G_Wireless.SG_Uhf.param_modulation)
	{
	case 4:
		EVM_Temp = rx_error_magnitude_tmp / 393.6; //4-QAM Error Vector Magnitude (EVM) = Rx Error Magnitude / (640 x 0.615)
		break;
	case 16:
		EVM_Temp = rx_error_magnitude_tmp / 557.44; //16-QAM Error Vector Magnitude (EVM) = Rx Error Magnitude / (640 x 0.871)
		break;
	case 64:
		EVM_Temp = rx_error_magnitude_tmp / 640; //64-QAM Error Vector Magnitude (EVM) = Rx Error Magnitude / 640
		break;
	}
	//	printk("EVM =  %d   ",rx_error_magnitude.Rx_Error_Magnitude);
	return EVM_Temp;
}
#define RSSI_AGC_COEF_1
#define RSSI_AGC_COEF_2
#define RSSI_AGC_COEF_3
#define RSSI_AGC_COEF_4
#define RSSI_AGC_COEF_5
#define RSSI_AGC_COEF_6
#define RSSI_AGC_COEF_7
#define RSSI_AGC_COEF_8

void CMX7164_Store_statistics(void)
{
	CMX7164_Read_WORD((CMX_WORD*) &agc_gain_rssi);
	RSSI_Statistic = (short) (agc_gain_rssi.Word_val << 4) / 16;

//	RSSI_Statistic -= (20+agc_gain_rssi.Bit_val.AGC_Gain*6);

	switch(agc_gain_rssi.Bit_val.AGC_Gain)
	{
	case 0:
		break;
	case 1:
		break;
	case 2:
		RSSI_Statistic -= 44;
		break;
	case 3:
		RSSI_Statistic -= 38;
		break;
	case 4:
		RSSI_Statistic -= 44;
		break;
	case 5:
		RSSI_Statistic -= 50;
		break;
	case 6:
		RSSI_Statistic -= 56;
		break;
	case 7:
		RSSI_Statistic -= 62;
		break;
	}

}
/*********************************************************************************************/

/*********************************************************************************************/
void CMX7164_Print_RSSI_statistics(void)
{
	printk("RSSI = ");
	if ((K_COEFFICIENT_OF_RSSI == 0) && (B_COEFFICIENT_OF_RSSI == 0))
	{
		printk("%d dbm   ", RSSI_Statistic);
		printk("Not calibrated\r\n");
	}
	else
	{
		printk("%d dbm\r\n", (RSSI_Statistic * K_COEFFICIENT_OF_RSSI+ B_COEFFICIENT_OF_RSSI));
	}
}
/*********************************************************************************************/

/*********************************************************************************************/
void CMX7164_Reinitialize(void)
{
	CMX7164_Reinit = 1;
	vTaskResume(mac_task_handle);
}
/*********************************************************************************************/

/*********************************************************************************************/
void CMX7164_GoToIdle(void)
{
	modem_mode_and_control.Word_val = 0x0000; //6B
	CMX7164_Write_WORD((CMX_WORD*) &modem_mode_and_control);
}
/*********************************************************************************************/
void CMX7164_FSK_GMSK_set_deviation(unsigned int deviation_hz,unsigned int symol_rate)
{
	unsigned int reg_val;
	if((ConfigRoot.G_Wireless.SG_Uhf.param_modulation == 4) || (ConfigRoot.G_Wireless.SG_Uhf.param_modulation == 5))
		reg_val = (deviation_hz * 3 * 0x800 * 16) / (symol_rate * 5);
	else
		reg_val = (deviation_hz * 3 * 0x800 * 4) / (symol_rate);
	signal_control.Word_val = 0xA000 | (reg_val & 0xFFF);
	CMX7164_Write_WORD((CMX_WORD*) &signal_control);
}

/*********************************************************************************************/

/*********************************************************************************************/
void CMX7164_Set_FEC(void)
{
	switch (CMX7164_Modulation_Type)
	{
		case 1:
		case 2:
		case 3:
			switch(ConfigRoot.G_Wireless.SG_Uhf.param_fec)
			{
			case 0:
			case 1:
			case 2:
				UsageBlockType = 0;
				ConfigRoot.G_Wireless.SG_Uhf.param_fec = 2;
				break;
			case 3:
				UsageBlockType = 2;
				break;
			case 4:
				UsageBlockType = 8;
				break;
			case 5:
				UsageBlockType = 10;
				break;
			default:
				UsageBlockType = 0;
				ConfigRoot.G_Wireless.SG_Uhf.param_fec = 2;
				break;
			}
			break;
		case 4:
		case 5:
			switch(ConfigRoot.G_Wireless.SG_Uhf.param_fec)
			{
			case 0:
			case 1:
				break;
			case 2:
			case 3:
			case 4:
			case 5:
			default:
				ConfigRoot.G_Wireless.SG_Uhf.param_fec = 1;
				break;
			}
			UsageBlockType = 2;
			break;
		case 6:
			switch(ConfigRoot.G_Wireless.SG_Uhf.param_fec)
			{
			case 0:
			case 1:
				break;
			case 2:
			case 3:
			case 4:
			case 5:
			default:
				ConfigRoot.G_Wireless.SG_Uhf.param_fec = 1;
				break;
			}
			UsageBlockType = 3;
			break;
	}
}

